package net.fkzg.framework.application.token;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

public class CustomTokenUtils {

    private static final String userIdKey = "i";
    private static final String userTypeKey = "t";
    private static final String expiresAtStampKey = "e";

    public static String saveToken(Long userId, Integer userType, Integer timeout) {
        Date expiresAt = Date.from(LocalDateTime.now().plusMinutes(timeout).atZone(ZoneId.systemDefault()).toInstant());
        Map<String, String> tokenMap = new HashMap<>();
        tokenMap.put(userIdKey, CustomBase62.convert(userId));
        tokenMap.put(userTypeKey, userType.toString());
        tokenMap.put(expiresAtStampKey, CustomBase62.convert(expiresAt.getTime()));
        return CustomBase62.encode(objToFormStr(tokenMap).getBytes());
    }

    public static CustomToken getToken(String token) {
        try {
            Map<String, String> obj = formStrToObj(new String(CustomBase62.decode(token)));
            long et = CustomBase62.revert(obj.get(expiresAtStampKey));
            if (et + 5 * 60 * 1000L < System.currentTimeMillis()) {//失效超5分钟了
                return null;
            }
            CustomToken jwtToken = new CustomToken();
            jwtToken.setUserId(CustomBase62.revert(obj.get(userIdKey)));
            jwtToken.setUserType(Integer.parseInt(obj.get(userTypeKey)));
            jwtToken.setExpiresAtStamp(et);
            return jwtToken;
        } catch (Throwable t) {
            return null;
        }
    }

    private static String objToFormStr(Map<String, String> tokenMap) {
        try {
            StringBuilder sb = new StringBuilder();
            List<String> keyList = new ArrayList<>(tokenMap.keySet());
            Collections.shuffle(keyList);
            for (String key : keyList) {
                sb.append(key).append('@').append(tokenMap.get(key)).append('&');
            }
            if (sb.length() > 1) {
                sb.deleteCharAt(sb.length() - 1);
            }
            return sb.toString();
        } catch (Throwable ignore) {
            return "";
        }
    }

    private static Map<String, String> formStrToObj(String str) {
        Map<String, String> resMap = new HashMap<>();
        String[] reArray = str.split("&");
        for (String tmp : reArray) {
            int eqIndex = tmp.indexOf("@");
            resMap.put(tmp.substring(0, eqIndex), tmp.substring(eqIndex + 1));
        }
        return resMap;
    }

}
